package com.yonyou.pmclouds.project.rmiimpl;

import com.alibaba.dubbo.config.annotation.Service;
import com.yonyou.pmclouds.ApplicationConsts;
import com.yonyou.pmclouds.basecom.bp.template.SingleUpdateBpTemplate;
import com.yonyou.pmclouds.basecom.exception.BusinessException;
import com.yonyou.pmclouds.basecom.runtime.RuntimeEnvironment;
import com.yonyou.pmclouds.plan.rmiitf.IScheduleService;
import com.yonyou.pmclouds.project.entity.ProjectVO;
import com.yonyou.pmclouds.project.entity.ProjectViewVO;
import com.yonyou.pmclouds.project.mapper.ProjectMapper;
import com.yonyou.pmclouds.project.processor.EndUpdateTeamProcessor;
import com.yonyou.pmclouds.project.processor.OutterUpdateEnterpriseToTeamProcessor;
import com.yonyou.pmclouds.project.processor.OutterUpdateManagerToTeamProcessor;
import com.yonyou.pmclouds.project.rmiitf.ProjectMaintain;
import com.yonyou.pmclouds.project.rmiitf.ProjectOutterMaintain;
import com.yonyou.pmclouds.project.rmiitf.ProjectSimpleQuery;
import com.yonyou.pmclouds.projectstatus.entity.ProjectStatusVO;
import com.yonyou.pmclouds.projectstatus.rmiitf.ProjectStatusOutterMaintain;
import com.yonyou.pmclouds.projectstatus.util.ProjectStatusUtils;
import com.yonyou.pmclouds.projecttype.entity.ProjectTypeVO;
import com.yonyou.pmclouds.projecttype.rmiitf.ProjectTypeOutterMaintain;
import com.yonyou.pmclouds.team.rmiimpl.TeamMaintainForProject;
import com.yonyou.pmclouds.team.rmiitf.TeamEnterpriseMaintain;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;

@Service(version = ApplicationConsts.APPLICATION_VERSION, interfaceClass = ProjectOutterMaintain.class)
public class ProjectOutterMaintainImpl implements ProjectOutterMaintain {

    public static String PROJECT_INSERT = "insert";
    public static String PROJECT_UPDATE = "update";

    @Autowired
    private ProjectTypeOutterMaintain typeOutterMaintain;
    @Autowired
    private ProjectStatusOutterMaintain statusOutterMaintain;
    @Autowired
    private ProjectMapper projectMapper;
    @Autowired
    private ProjectSimpleQuery projectSimpleQuery;
    @Autowired
    private ProjectMaintain projectMaintain;
    @Autowired
    private TeamEnterpriseMaintain teamEnterpriseMaintain;
    @Autowired
    private TeamMaintainForProject teamMemberMaintain;
    @Autowired
    private IScheduleService scheduledService;

    @Override
    public ProjectViewVO insertFromOutter(ProjectViewVO projectViewVO) throws BusinessException {

        // 检查外部保存的项目是否已经存在
        ProjectViewVO outPrjVO = projectSimpleQuery.queryProjectViewVOByPkSrc(RuntimeEnvironment.getTenantId(),projectViewVO.getPkSrc());
        if(outPrjVO != null){
            return outPrjVO;
        }

        ProjectStatusVO statusVO = this.genStatusVOForProject(projectViewVO.getProjectStateCloudVO(), PROJECT_INSERT);

        if (statusVO.getStateSort() != null) {
            byte status = ProjectStatusUtils.getTransStatus(statusVO);
            projectViewVO.setProjectState(status);
        }

        projectViewVO.setPkProjectStatus(statusVO.getPkProjectStatus());

        ProjectTypeVO typeVO = this.genTypeVOForProject(projectViewVO.getProjectTypeCloudVO(), PROJECT_INSERT);

        projectViewVO.setPkProjectType(typeVO.getPkProjectType());

        ProjectViewVO projectViewVOAuto = projectMaintain.insert(projectViewVO);

        scheduledService.savePlanAuto(projectViewVO);

        return projectViewVOAuto;
    }

    @Override
    public ProjectVO updateFromOutter(ProjectVO newProject, String enterprise) throws BusinessException {

        if (StringUtils.isEmpty(newProject.getPkSrc()))
            throw new BusinessException("项目档案来源主键为空");

        ProjectVO[] origProjects = projectMapper.queryVOBySrcIds(newProject.getPkTenant(), new String[]{newProject.getPkSrc()});

        if (ArrayUtils.isEmpty(origProjects))
            return null;

        ProjectVO origProject = origProjects[0];

        //TODO 是否在没有原始数据时进行新增
        if (origProject == null)
            return null;

        String origManager = origProject.getManager();
        String newManager = newProject.getManager();

        if(StringUtils.isNotEmpty(origManager) && StringUtils.isEmpty(newManager)){
            throw new BusinessException("项目经理不能修改为非友工程人员");
        }

        ProjectVO cloneOrigVO = (ProjectVO) origProject.clone();

        ProjectVO toUpdProjectVO = getUpdProjectVO(cloneOrigVO, newProject);
        update(origProject, toUpdProjectVO, enterprise);

        return toUpdProjectVO;
    }

    private void update(ProjectVO origProject, ProjectVO toUpdProjectVO, String enterprise) throws BusinessException {
        // 编码、名称、描述、责任人
        String[] outterUpdateFields = new String[]{ProjectVO.SCODE, ProjectVO.SNAME, ProjectVO.DESCRIPTION, ProjectVO.MANAGER,
                ProjectVO.PROJECT_STATE, ProjectVO.END_DATE, ProjectVO.PROJECT_STATUS, ProjectVO.PROJECT_TYPE, ProjectVO.ISKEY,ProjectVO.ADDRESS,ProjectVO.LATITUDE,ProjectVO.LONGITUDE};

        SingleUpdateBpTemplate<ProjectVO> bp = new SingleUpdateBpTemplate<>(projectMapper, outterUpdateFields);
        bp.addAfterProcessor(new OutterUpdateManagerToTeamProcessor(teamMemberMaintain, enterprise));
        bp.addAfterProcessor(new OutterUpdateEnterpriseToTeamProcessor(teamEnterpriseMaintain, enterprise));

        if (origProject.getProjectState() != toUpdProjectVO.getProjectState()) {
            bp.addAfterProcessor(new EndUpdateTeamProcessor(teamMemberMaintain));
        }

        bp.update(toUpdProjectVO);
    }

    private ProjectVO getUpdProjectVO(ProjectVO origProject, ProjectVO project) throws BusinessException {

        ProjectStatusVO newStatusVO = genStatusVOForProject(project.getProjectStateCloudVO(), PROJECT_UPDATE);
        ProjectTypeVO typeVO = genTypeVOForProject(project.getProjectTypeCloudVO(), PROJECT_UPDATE);

        origProject.setPkProjectStatus(newStatusVO.getPkProjectStatus());
        origProject.setProjectStateCloudVO(newStatusVO);
        origProject.setPkProjectType(typeVO.getPkProjectType());
        origProject.setScode(project.getScode());
        origProject.setSname(project.getSname());
        origProject.setDescription(project.getDescription());
        origProject.setManager(project.getManager());
        origProject.setIskey(project.getIskey());
        origProject.setProjectState(ProjectStatusUtils.getTransStatus(newStatusVO));
        origProject.setAddress(project.getAddress());
        origProject.setLatitude(project.getLatitude());
        origProject.setLongitude(project.getLongitude());
        // 结束日期根据综合验收日期
        return origProject;
    }

    @Override
    public ProjectVO deleteFromOutter(ProjectVO project) throws BusinessException {

        if (StringUtils.isEmpty(project.getPkSrc()))
            throw new BusinessException("项目档案来源主键为空");

        ProjectVO[] projectVOs = projectMapper.queryVOBySrcIds(project.getPkTenant(), new String[]{project.getPkSrc()});

        if (ArrayUtils.isEmpty(projectVOs))
            return null;

        ProjectVO origProject = projectVOs[0];

        projectMaintain.delete(origProject.getPkProject(), origProject.getChangeFlag(), null);

        return origProject;
    }

    private ProjectStatusVO genStatusVOForProject(ProjectStatusVO statusVO, String method) throws BusinessException {

        if (statusVO == null)
            return new ProjectStatusVO();

        ProjectStatusVO newStatusVO;
        if (PROJECT_INSERT.equals(method)) {
            newStatusVO = statusOutterMaintain.insertFromOutter(statusVO);
            newStatusVO.setStateSort(statusVO.getStateSort());
            return newStatusVO;
        } else if (PROJECT_UPDATE.equals(method)) {
            newStatusVO = statusOutterMaintain.updateFromOutter(statusVO);
            newStatusVO.setStateSort(statusVO.getStateSort());
            return newStatusVO;
        }

        return statusVO;
    }

    private ProjectTypeVO genTypeVOForProject(ProjectTypeVO typeVO, String method) throws BusinessException {

        if (typeVO == null)
            return new ProjectTypeVO();

        if (PROJECT_INSERT.equals(method)) {
            return typeOutterMaintain.insertFromOutter(typeVO);
        } else if (PROJECT_UPDATE.equals(method)) {
            return typeOutterMaintain.updateFromOutter(typeVO);
        }

        return typeVO;
    }
}
